from flask import Blueprint, render_template, jsonify, request, send_file
import pandas as pd
import numpy as np
from pathlib import Path
import os
import sys
import traceback
from other_transport_analysis import main as generate_analysis

# 创建Blueprint
other_transport_bp = Blueprint('other_transport', __name__)

def get_resource_path(relative_path):
    """获取资源文件的绝对路径，支持开发环境和打包环境"""
    if hasattr(sys, '_MEIPASS'):
        # PyInstaller 打包环境
        base_path = sys._MEIPASS
    else:
        # 开发环境
        base_path = os.path.dirname(os.path.abspath(__file__))
    
    return os.path.join(base_path, relative_path)

# 配置数据文件路径
DATA_DIR = Path("data")
ALLDATA_DIR = DATA_DIR / "alldata"
RESULT_FILE = ALLDATA_DIR / "其他交通工具费用超标分析结果.xlsx"
DICT_FILE = ALLDATA_DIR / "二等座票价标准.csv"

# 确保目录存在
ALLDATA_DIR.mkdir(parents=True, exist_ok=True)

# 全局变量存储当前数据
current_other_data = None

def remap_price_standards():
    """重新映射票价标准到分析结果"""
    try:
        # 检查必要的文件是否存在
        if not DICT_FILE.exists():
            raise FileNotFoundError("票价标准字典文件不存在")
        if not RESULT_FILE.exists():
            raise FileNotFoundError("分析结果文件不存在")

        # 读取票价标准字典
        standards_df = pd.read_csv(DICT_FILE, encoding='utf-8-sig')
        # 创建票价标准字典
        price_standards = standards_df.set_index(['起始地名称', '目的地名称'])['二等座票价标准'].to_dict()

        # 读取分析结果文件
        result_df = pd.read_excel(RESULT_FILE, engine='openpyxl')

        # 重新映射票价标准
        def map_standard_price(row):
            route_key = (row['起始地名称'], row['目的地名称'])
            return price_standards.get(route_key, np.nan)

        # 更新二等座票价标准
        result_df['二等座票价标准'] = result_df.apply(map_standard_price, axis=1)

        # 重新计算超出率
        result_df['超出率'] = ((result_df['含税金额'] - result_df['二等座票价标准']) / result_df['二等座票价标准']) * 100
        result_df.loc[result_df['二等座票价标准'] == 0, '超出率'] = None
        result_df['超出率'] = result_df['超出率'].apply(lambda x: f"{x:.2f}%" if pd.notnull(x) else None)

        # 保存更新后的结果
        result_df.to_excel(RESULT_FILE, index=False, engine='openpyxl')
        return True

    except Exception as e:
        print(f"重新映射票价标准时出错: {str(e)}")
        raise

@other_transport_bp.route('/other-transport')
def other_transport():
    """渲染其他交通费用超标分析页面"""
    return render_template('pages/other_transport.html', active_page='other_transport')

@other_transport_bp.route('/other-transport/check-dictionary-status')
def check_dictionary_status():
    """检查字典文件是否存在"""
    exists = DICT_FILE.exists()
    return jsonify({'exists': exists})

def create_other_route_price_standards(transport_data):
    """
    创建其他交通工具路线票价标准字典
    
    Args:
        transport_data (pd.DataFrame): 交通费用数据
        
    Returns:
        dict: 路线票价标准字典
    """
    # 筛选非高铁动车记录
    other_transport_mask = ~transport_data["交通工具名称"].str.contains("高铁|动车", na=False)
    other_transport_data = transport_data[other_transport_mask]
    
    # 计算每个路线的标准票价（使用众数）
    price_standards = (other_transport_data
        .groupby(["起始地名称", "目的地名称"])["含税金额"]
        .agg(lambda x: x.mode().iloc[0])
        .reset_index()
        .rename(columns={"含税金额": "二等座票价标准"}))
    
    # 转换为字典格式
    route_price_dict = price_standards.set_index(
        ["起始地名称", "目的地名称"])["二等座票价标准"].to_dict()
    
    # 为所有路线设置默认值
    all_routes = set(zip(transport_data['起始地名称'], transport_data['目的地名称']))
    for route in all_routes:
        if route not in route_price_dict:
            route_price_dict[route] = 0
            
    return route_price_dict

@other_transport_bp.route('/other-transport/generate-dictionary', methods=['POST'])
def generate_dictionary():
    """生成其他交通工具费用超标分析结果"""
    try:
        # 调用分析函数生成结果
        generate_analysis()
        return jsonify({'success': True})

    except Exception as e:
        print(f"生成分析结果时出错: {str(e)}")  # 打印错误信息
        return jsonify({
            'success': False,
            'error': f'生成分析结果时出错: {str(e)}'
        })

@other_transport_bp.route('/other-transport/match-and-analyze', methods=['POST'])
def match_and_analyze():
    """重新匹配分析数据"""
    try:
        # 检查字典文件是否存在
        if not DICT_FILE.exists():
            return jsonify({
                'success': False,
                'error': '请先生成二等座票价标准字典'
            })

        # 检查结果文件是否存在
        if not RESULT_FILE.exists():
            return jsonify({
                'success': False,
                'error': '分析结果文件不存在，请先生成分析结果'
            })

        # 执行重新映射
        remap_price_standards()
        return jsonify({'success': True})

    except Exception as e:
        print(f"匹配分析时出错: {str(e)}")  # 打印错误信息
        return jsonify({
            'success': False,
            'error': f'匹配分析时出错: {str(e)}'
        })

@other_transport_bp.route('/other-transport/get-other-data', methods=['POST'])
def get_other_data():
    """获取其他交通费用超标数据"""
    try:
        # 检查结果文件是否存在
        if not RESULT_FILE.exists():
            return jsonify({
                'error': '请先执行数据匹配分析'
            }), 400

        try:
            # 尝试读取Excel文件，使用openpyxl引擎
            df = pd.read_excel(RESULT_FILE, engine='openpyxl')
        except Exception as e:
            return jsonify({
                'error': f'读取Excel文件失败: {str(e)}'
            }), 400

        if df.empty:
            return jsonify({
                'error': '分析结果为空'
            }), 400

        # 获取所有列名
        all_columns = df.columns.tolist()

        # 处理请求参数
        data = request.get_json()
        get_all = data.get('all', False) if data else False

        if get_all:
            # 返回所有数据
            result_data = df.to_dict('records')
        else:
            # 分页处理
            page = int(request.form.get('page', 1))
            per_page = 20
            start_idx = (page - 1) * per_page
            end_idx = start_idx + per_page
            
            result_data = df.iloc[start_idx:end_idx].to_dict('records')

        # 处理数据中的特殊值
        for record in result_data:
            for key, value in record.items():
                if pd.isna(value):
                    record[key] = None
                elif isinstance(value, (np.int64, np.float64)):
                    record[key] = float(value) if isinstance(value, np.float64) else int(value)

        return jsonify({
            'data': result_data,
            'all_columns': all_columns,
            'total_records': len(df)
        })

    except Exception as e:
        return jsonify({
            'error': f'获取数据时出错: {str(e)}'
        }), 500

@other_transport_bp.route('/other-transport/download-other-excel')
def download_other_excel():
    """下载其他交通费用超标分析结果"""
    try:
        if not RESULT_FILE.exists():
            return jsonify({
                'error': '分析结果文件不存在'
            }), 404

        # 读取Excel文件
        df = pd.read_excel(RESULT_FILE, engine='openpyxl')
        
        # 获取阈值参数和选择的字段
        threshold = request.args.get('threshold', type=float)
        selected_fields = request.args.getlist('fields')
        
        # 如果指定了阈值，进行数据筛选
        if threshold is not None:
            # 将超出率列转换为数值
            df['超出率_数值'] = df['超出率'].apply(lambda x: float(x.replace('%', '')) if isinstance(x, str) and x != '-' else None)
            # 筛选大于等于阈值的数据
            df = df[df['超出率_数值'] >= threshold]
            # 删除临时列
            df = df.drop('超出率_数值', axis=1)

        # 如果指定了字段，只保留选择的字段
        if selected_fields:
            # 确保所有请求的字段都存在
            valid_fields = [field for field in selected_fields if field in df.columns]
            if not valid_fields:
                return jsonify({
                    'error': '没有找到有效的字段'
                }), 400
            df = df[valid_fields]

        # 如果数据为空，返回错误
        if df.empty:
            return jsonify({
                'error': '筛选后没有符合条件的数据'
            }), 400

        # 创建临时文件名
        filename_parts = ['其他交通费用超标分析结果']
        if threshold is not None:
            filename_parts.append(f'阈值{threshold}')
        filename = f"{'_'.join(filename_parts)}.xlsx"
        
        # 使用get_resource_path获取正确的文件路径
        temp_file = get_resource_path(os.path.join('data', 'alldata', filename))
        
        # 确保输出目录存在
        os.makedirs(os.path.dirname(temp_file), exist_ok=True)
        
        try:
            # 保存筛选后的数据
            df.to_excel(temp_file, index=False, engine='openpyxl')
            
            return send_file(
                temp_file,
                as_attachment=True,
                download_name=filename,
                mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            )
        except Exception as e:
            return jsonify({
                'error': f'保存文件时出错: {str(e)}'
            }), 500

    except Exception as e:
        return jsonify({
            'error': f'下载文件时出错: {str(e)}'
        }), 500

@other_transport_bp.route('/other-transport/check-result-file')
def check_result_file():
    """检查分析结果文件是否存在"""
    exists = RESULT_FILE.exists()
    return jsonify({'exists': exists}) 